# -*- coding: utf-8 -*-
"""
Created on Sun Aug 26 16:51:50 2012

@author: Tomek
"""

import CPPparse
class EnumType:
    def __init__(self,name):
        self.name=name
    def equals(self,a):
        if self.name==a.name:
            return True
        return False
        
class EnumTypeArray:
    def __init__(self):
        self.data=[]
    def exist(self,x):
        for p in self.data:
            if p.equals(x):
                return True
        return False
    def append(self,x):
        if self.exist(x)==False:
            self.data.append(x)
enumsTypes=EnumTypeArray()
class ReplaceType:
    def __init__(self,oldName,oldExtra,oldArray,newName,newExtra,newArray):
        self.OldName=oldName
        self.OldExtra=oldExtra
        self.OldArray=oldArray
        self.NewName=newName
        self.NewExtra=newExtra
        self.NewArray=newArray
    def oldEquals(self,a):
        if a.OldName==self.OldName and a.OldExtra==self.OldExtra and a.OldArray==self.OldArray:
            return True
        return False
        
class ReplaceTypeArray:
    def __init__(self):
        self.data=[]
    def exist(self,x):
        for p in self.data:
            if p.oldEquals(x):
                return True
        return False
    def append(self,x):
        if self.exist(x)!=True:
            self.data.append(x)
replaceTypes=ReplaceTypeArray()

def getTableWithoutEqualSpecifier(f):
    ntbl=[]
    for x in f:
        if len(x)!=0:
            if x[0]!="=":
                ntbl.append(x)
    return ntbl
def tableHasEqualSpecifier(f):
    for x in f:
        if len(x)!=0:
            if x[0]=="=":
                return True
    return False

def tableEquals(ff,ss,eqType=0):
    f=getTableWithoutEqualSpecifier(ff)
    s=getTableWithoutEqualSpecifier(ss)
    if len(f)!=len(s):
        return False
    for x in range(0,len(f)):
        if f[x]!=s[x]:
            return False
    return True
    
def tableContains(f,r):
    for x in f:
        if tableEquals(x,r):
            return True
    return False
class ConvertObject:
    def __init__(self,nm,ptr,ref,nor):
        self.pointer=ptr
        self.reference=ref
        self.definedTemplates=[]
        self.name=nm
        self.normal=nor
    def merge(self,x):
        if self.name!=x.name:
            return False
        if self.pointer or x.pointer:
            self.pointer=True
        if self.reference or x.reference:
            self.reference=True
        if self.normal or x.normal:
            self.normal=True
        for xx in x.definedTemplates:
            if tableContains(self.definedTemplates,xx)==False:
                self.definedTemplates.append(xx)

                
    def parseTemplates(self,x):
        self.definedTemplates=[]
        defTable=x.split("|")
        for x in defTable:
            p=x.split(";")
            currTbl=[]
            for xx in p:
                currTbl.append(xx)
            self.definedTemplates.append(currTbl)
    def equals(self,a):
        if self.name==a.name:
            return True
        return False
        
            
class ConvertObjectArray:
    def __init__(self):
        self.data=[]
    def exist(self,x):
        for p in self.data:
            if p.equals(x):
                return True
        return False
    def append(self,x):
        if self.exist(x)==False:
            defTmplStr=""
            for p in x.definedTemplates:
                ds=""
                for i in p:
                    if ds!="":
                        ds=ds+";"
                        ds=ds+i
                if ds!="":
                    if defTmplStr!="":
                        defTmplStr=defTmplStr+"|"
                        defTmplStr=defTmplStr+ds

            if x.reference==True or x.pointer==True:
                if x.normal==False and x.reference==True:
                    x.normal=True

                self.data.append(x)
        else:
            for p in self.data:
                if p.equals(x):
                    p.merge(x)
def checkLuaType(st):
    if len(st)<4:
        return False
    if st[len(st)-7:]=="_LUAREF" or st[len(st)-7:]=="_LUAPTR" or st[len(st)-4:]=="_LUA":
        return True
    else:
        return False
def getOldTypeFromLua(st):
    if len(st)<4:
        return st
    if st[len(st)-7:]=="_LUAREF":
        return st[:len(st)-7]+"&"
    elif st[len(st)-7:]=="_LUAPTR":
        return st[:len(st)-7]+"*"
    elif st[len(st)-4:]=="_LUA":
        return st[:len(st)-4]
    else:
        return st
def replaceType(t):
    nt=CPPparse._Type()
    nt.data=t.data
    for r in replaceTypes.data:
        if t["name"]==r.OldName or r.OldName=="__ANY__":
            if t["extra"]==r.OldExtra or r.OldExtra=="__ANY__":
                if t["array"]==r.OldArray or r.OldArray=="__ANY__":
                    if r.NewName!="__SAME__":
                        nt.data["name"]=r.NewName
                    if r.NewExtra!="__SAME__":
                        nt.data["extra"]=r.NewExtra
                    if r.NewArray!="__SAME__":
                        nt.data["array"]=r.NewArray
    contbl=[]

    if nt.data.has_key("templatesConverted")!=True:
        for x in range(0,len(nt["templates"])):
            nt["templates"][x]=replaceType(nt["templates"][x])
            if nt["templates"][x]["isTemplate"]==True:
                if len(nt["templates"][x]["name"])<4 or nt["templates"][x]["name"][len(nt["templates"][x]["name"])-4:]!="_GET":
                    n=CPPparse._Type()
                    n.parseType(nt["templates"][x]["name"]+"_GET",0)
                    n.data["isTemplate"]=True
                    contbl.append(n)
            else:
                if checkLuaType(nt["templates"][x]["name"]):
                    n=CPPparse._Type()
                    n.parseType("darklua::TypeLuaConverter<"+nt["templates"][x]["fullname"]+","+getOldTypeFromLua(nt["templates"][x]["fullname"])+">",0)
                    contbl.append(n)
                else:
                    n=CPPparse._Type()
                    n.parseType("darklua::TypeNoneConverter<"+nt["templates"][x]["fullname"]+">",0)
                    contbl.append(n)
        nt.data["templatesConverted"]=True
    nt.data["templates"]=nt["templates"]+contbl
    nt.reloadFullname()
    nt.reloadTemplateName()
    return nt
def readParsingFile(fname):
    ns=[]
    f=open(fname,"r")
    for x in f.readlines():
        rstr=x
        rstr=rstr.replace("\n","")
        nss=CPPparse.parse(rstr,1,False)
        ns.append(nss)
    f.close()
    retNs=ns[0]
    
    for x in ns:
        retNs.merge(x,True)
    return retNs
    
configFile="config.txt"

convertObjects=ConvertObjectArray()
globalNamespace=readParsingFile(configFile)

for x in globalNamespace.getObjects("Typedef"):
    xx=ReplaceType(x["name"],"__ANY__","__ANY__",x["type"]["fullname"],"__SAME__","__SAME__")
    replaceTypes.append(xx)
for x in globalNamespace.getObjects("Class"):
    xx=ConvertObject(x["name"],False,False,False)
    xx.definedTemplates=[]
    convertObjects.data.append(xx)
for xt in globalNamespace.getObjects("Typedef"):
    x=xt["type"]
    if x["isTemplate"]:
        continue
    x=replaceType(x)
    xx=ConvertObject(x["name"],x["extra"]=="*",x["extra"]=="&",x["extra"]=="")
    defTmpls=[]
    for p in x["templates"]:
        if p["isTemplate"]==False:
            p.reloadFullname()
            defTmpls.append(p["fullname"])
    if len(defTmpls)!=0:
        defTmpls.append("="+xt["name"])
    xx.definedTemplates.append(defTmpls)
    convertObjects.append(xx)
for x in globalNamespace.getObjects("Type"):
    if x["isTemplate"]:
        continue
    x=replaceType(x)
    xx=ConvertObject(x["name"],x["extra"]=="*",x["extra"]=="&",x["extra"]=="")
    defTmpls=[]
    for p in x["templates"]:
        if p["isTemplate"]==False:
            p.reloadFullname()
            defTmpls.append(p["fullname"])
    xx.definedTemplates.append(defTmpls)
    convertObjects.append(xx)
for x in globalNamespace.getObjects("Enum"):
    convertObjects.append(ConvertObject(x["name"],False,True,True))
for x in globalNamespace.getObjects("Function"):
    convertObjects.append(ConvertObject(x["name"],True,True,True))
"""
for r in replaceTypes.data:
    print "REPLACE_TYPE"
    print r.OldName
    print r.OldExtra
    print r.OldArray
    print r.NewName
    print r.NewExtra
    print r.NewArray
    """
for c in convertObjects.data:
    print "CONVERT_OBJECT"
    print c.name
    print c.pointer
    print c.reference
    print c.normal
    defTmplStr=""
    for x in c.definedTemplates:
        ds=""
        for i in x:
            if ds!="":
                ds=ds+";"
            ds=ds+i
        if ds!="":
            if defTmplStr!="":
                defTmplStr=defTmplStr+"|"
            defTmplStr=defTmplStr+ds
    if defTmplStr=="":
        defTmplStr="__NONE__"
    print defTmplStr
